package org.jeecg.modules.monitoring.j_monitoring.controller;

import java.util.*;
import java.util.stream.Collectors;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xkcoding.http.util.StringUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.monitoring.j_monitoring.entity.*;
import org.jeecg.modules.monitoring.j_monitoring.entity.home.CabinetInfo;
import org.jeecg.modules.monitoring.j_monitoring.mapper.MCabinetMapper;
import org.jeecg.modules.monitoring.j_monitoring.service.IGatewayWarningService;
import org.jeecg.modules.monitoring.j_monitoring.service.IMCabinetService;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;

import org.jeecg.modules.monitoring.j_monitoring.vo.MCabinetDevice;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.system.base.controller.JeecgController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jeecg.common.aspect.annotation.AutoLog;

/**
 * @Description: 机柜
 * @Author: xiaoyq
 * @Date: 2023-02-22
 * @Version: V1.0
 */
@Api(tags = "机柜")
@RestController
@RequestMapping("/j_monitoring/mCabinet")
@Slf4j
public class MCabinetController extends JeecgController<MCabinet, IMCabinetService> {
    @Autowired
    private IGatewayWarningService gatewayWarningService;

    /**
     * 分页列表查询
     *
     * @param mCabinet
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "机柜-分页列表查询")
    @RequiresPermissions("机柜:查询")
    @ApiOperation(value = "机柜-分页列表查询", notes = "机柜-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(MCabinet mCabinet,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {

        QueryWrapper<MCabinet> queryWrapper = QueryGenerator.initQueryWrapper(mCabinet, req.getParameterMap());
        Page<MCabinet> page = new Page<MCabinet>(pageNo, pageSize);
        IPage<MCabinet> pageList = service.page(page, queryWrapper);
        return Result.OK(pageList);
    }

    @RequiresPermissions("机柜:查询")
    @ApiOperation(value = "根据机柜信息查询设备列表", notes = "根据机柜信息查询设备列表")
    @GetMapping(value = "/queryEquipmentListBy")
    public Result<?> queryEquipmentListBy(MCabinet mCabinet,
                                          HttpServletRequest req) {
        QueryWrapper<MCabinet> queryWrapper = QueryGenerator.initQueryWrapper(mCabinet, req.getParameterMap());
        List<MCabinet> cabinets = service.list(queryWrapper);
        List<MCabinetDevice> deviceList = new ArrayList<>();
        List<String> idList = new ArrayList<>();
        cabinets.forEach(mCabinet1 -> idList.add(mCabinet1.getId()));
        List<MCabinetDevice> dataList = service.getDeviceListByIds(idList);
        return Result.OK(dataList);
    }

    @RequiresPermissions("机柜:查询")
    @ApiOperation(value = "根据机柜信息查询设备列表", notes = "根据机柜信息查询设备列表")
    @GetMapping(value = "/queryCabinetContenersByName")
    public Result<?> queryCabinetContenersByName(@RequestParam(name = "cabinetName") String cabinetName) {
        QueryWrapper<MCabinet> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().likeRight(MCabinet::getName, cabinetName);
        queryWrapper.orderByAsc("name");
        List<MCabinet> cabinets = service.list(queryWrapper);
        List<String> idList = new ArrayList<>();
        cabinets.forEach(mCabinet1 -> idList.add(mCabinet1.getId()));
        List<MCabinetDevice> deviceList = service.getDeviceListByIds(idList);


        List<String> ipList = deviceList.stream().filter((item)->"1".equals(item.getWhetherToMonitor())).map(e -> e.getIp()).collect(Collectors.toList());
        Map<String, GatewayWarning> warningIpList = gatewayWarningService.getWarningGroupByIp(ipList);


        JSONArray array = new JSONArray();
        for (int i = 0; i < cabinets.size(); i++) {
            MCabinet cabinet = cabinets.get(i);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", cabinet.getId());
            jsonObject.put("name", cabinet.getName());
            jsonObject.put("remarks", cabinet.getRemarks());
            //jsonObject.put("active",false);
            if (cabinet.getHeight() != null) {
                jsonObject.put("height", cabinet.getHeight().intValue());
            } else {
                jsonObject.put("height", 42);
            }
            jsonObject.put("warning", -1);

            JSONArray children = new JSONArray();

            for (int j = 0; j < deviceList.size(); j++) {
                MCabinetDevice mCabinetDevice = deviceList.get(j);
                if (mCabinetDevice.getCabinetId() != null && mCabinetDevice.getCabinetId().equals(cabinet.getId())) {


                    if (warningIpList.get(mCabinetDevice.getIp()) != null && "1".equals(mCabinetDevice.getWhetherToMonitor())) {
                        jsonObject.put("warning", warningIpList.get(mCabinetDevice.getIp()).getSeverity());
                        mCabinetDevice.setErrors(warningIpList.get(mCabinetDevice.getIp()).getSpecificProblems());
                        mCabinetDevice.setWarning(warningIpList.get(mCabinetDevice.getIp()).getSeverity());
                    }

                    children.add(mCabinetDevice);
                }
            }
            jsonObject.put("children", children);
            array.add(jsonObject);
        }
        return Result.OK(array);
    }

    /**
     * 添加
     *
     * @param mCabinet
     * @return
     */
    @AutoLog(value = "机柜-添加")
    @ApiOperation(value = "机柜-添加", notes = "机柜-添加")
    @RequiresPermissions("机柜:添加")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody MCabinet mCabinet) {
        service.save(mCabinet);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param mCabinet
     * @return
     */
    @AutoLog(value = "机柜-编辑")
    @ApiOperation(value = "机柜-编辑", notes = "机柜-编辑")
    @RequiresPermissions("机柜:编辑")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody MCabinet mCabinet) {
        service.updateById(mCabinet);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "机柜-通过id删除")
    @ApiOperation(value = "机柜-通过id删除", notes = "机柜-通过id删除")
    @RequiresPermissions("机柜:删除")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        service.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "机柜-批量删除")
    @ApiOperation(value = "机柜-批量删除", notes = "机柜-批量删除")
    @RequiresPermissions("机柜:批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.service.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @RequiresPermissions("机柜:查询")
    @ApiOperation(value = "机柜-通过id查询", notes = "机柜-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<MCabinet> queryById(@RequestParam(name = "id", required = true) String id) {
        MCabinet mCabinet = service.getById(id);
        if (mCabinet == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(mCabinet);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param mCabinet
     */
    @RequiresPermissions("机柜:导出")
    @RequestMapping(value = "/exportXls", method = RequestMethod.GET)
    @ApiOperation(value="机柜-导出", notes="机柜-导出")
    public ModelAndView exportXls(HttpServletRequest request, MCabinet mCabinet) {
        return super.exportXls(request, mCabinet, MCabinet.class, "机柜");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequiresPermissions("机柜:导入")
    @ApiOperation(value="机柜-导入", notes="机柜-导入")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, MCabinet.class);
    }

    @RequestMapping(value = "/getEquipmentAllList", method = RequestMethod.GET)
    public Result<?> getEquipmentAllList(EquipmentItem equipmentItem) {
        return Result.ok(service.getEquipmentAllList(equipmentItem.getId()));
    }

    /**
     * 获取机房/空调预警信息
     *
     * @return
     */
    @RequestMapping(value = "/getCabinetWarning", method = RequestMethod.GET)
    public Result<?> getCabinetWarning() {


        QueryWrapper<MCabinet> queryWrapper = new QueryWrapper();
        queryWrapper.orderByAsc("name");
        List<MCabinet> cabinets = service.list(queryWrapper);
        List<String> idList = new ArrayList<>();
        cabinets.forEach(mCabinet1 -> idList.add(mCabinet1.getId()));
        List<MCabinetDevice> deviceList = service.getDeviceListByIds(idList);

        Map<String, String> result = new HashMap<>();
        List<String> ipList = deviceList.stream().filter((item)->"1".equals(item.getWhetherToMonitor())).map(e -> e.getIp()).collect(Collectors.toList());
        Map<String, GatewayWarning> warningIpList = gatewayWarningService.getWarningGroupByIp(ipList);
        List<String> redList = new ArrayList<>();
        List<String> oracleList = new ArrayList<>();

        for (int i = 0; i < cabinets.size(); i++) {
            MCabinet cabinet = cabinets.get(i);


            for (int j = 0; j < deviceList.size(); j++) {
                MCabinetDevice mCabinetDevice = deviceList.get(j);
                //未加入监控的跳过
                if (!"1".equals(mCabinetDevice.getWhetherToMonitor())){
                    continue;
                }
                if (mCabinetDevice.getCabinetId() != null && mCabinetDevice.getCabinetId().equals(cabinet.getId())) {
                    if (warningIpList.get(mCabinetDevice.getIp()) != null) {
                        Integer severity = warningIpList.get(mCabinetDevice.getIp()).getSeverity();
                        //紧急 红色
                        if (severity == 0) {
                            redList.add(cabinet.getName());
                        }
                        //其他橙色
//                        if (!redList.contains(cabinet.getName())) {
//                            oracleList.add(cabinet.getName());
//                        }
                    }
                }
            }
        }

        result.put("lvDangerRoomIds", String.join(",", redList));
        result.put("lvWarningRoomIds", String.join(",", oracleList));

        return Result.ok(result);
    }


    /**
     * 获取机房信息
     *
     * @return
     */
    @RequestMapping(value = "/getCabinetInfo", method = RequestMethod.GET)
    public Result<?> getCabinetInfo() {


        QueryWrapper<MCabinet> queryWrapper = new QueryWrapper();
        queryWrapper.orderByAsc("name");
        List<MCabinet> cabinets = service.list(queryWrapper);
        List<String> idList = new ArrayList<>();
        cabinets.forEach(mCabinet1 -> idList.add(mCabinet1.getId()));
        List<MCabinetDevice> deviceList = service.getDeviceListByIds(idList);

        Map<String, Object> result = new HashMap<>();
        List<String> ipList = deviceList.stream().map(e -> e.getIp()).collect(Collectors.toList());
        Map<String, List<GatewayWarning>> warningIpList = gatewayWarningService.getWarningListGroupByIp(ipList);

        CabinetInfo dataRoom = new CabinetInfo();
        CabinetInfo netRoom = new CabinetInfo();


        for (MCabinetDevice mCabinetDevice : deviceList) {

            if ("数据机房".equals(mCabinetDevice.getMachineRoom())) {
                switch (mCabinetDevice.getDeviceType()) {
                    case "网络资源":
                        dataRoom.setNetwork(dataRoom.getNetwork()+1);
                        break;
                    case "计算资源":
                        dataRoom.setPhysics(dataRoom.getPhysics()+1);
                        break;
                    case "储存系统":
                        dataRoom.setStorage(dataRoom.getStorage()+1);
                        break;
                }


                if (warningIpList.get(mCabinetDevice.getIp())!=null && warningIpList.get(mCabinetDevice.getIp()).size() >0 && "1".equals(mCabinetDevice.getWhetherToMonitor())){
                    List<String> warList = dataRoom.getWarningList();
                    if (!warList.contains(mCabinetDevice.getCabinet() + "机柜")){
                        warList.add(mCabinetDevice.getCabinet() + "机柜");
                    }
                    dataRoom.setWarningList(warList);
                    dataRoom.setWarningCount(dataRoom.getWarningCount()+warningIpList.get(mCabinetDevice.getIp()).size());
                }

            }

            if ("网络机房".equals(mCabinetDevice.getMachineRoom())) {
                switch (mCabinetDevice.getDeviceType()) {
                    case "网络资源":
                        netRoom.setNetwork(netRoom.getNetwork()+1);
                        break;
                    case "计算资源":
                        netRoom.setPhysics(netRoom.getPhysics()+1);
                        break;
                    case "储存系统":
                        netRoom.setStorage(netRoom.getStorage()+1);
                        break;
                }

                if (warningIpList.get(mCabinetDevice.getIp())!=null && warningIpList.get(mCabinetDevice.getIp()).size() >0 && "1".equals(mCabinetDevice.getWhetherToMonitor())){
                    List<String> warList = netRoom.getWarningList();
                    if (!warList.contains(mCabinetDevice.getCabinet() + "机柜")){
                        warList.add(mCabinetDevice.getCabinet() + "机柜");
                    }
                    netRoom.setWarningList(warList);
                    netRoom.setWarningCount(netRoom.getWarningCount()+warningIpList.get(mCabinetDevice.getIp()).size());
                }

            }

        }

        Integer count = this.service.getCabinetCountByRoom("数据机房%");
        dataRoom.setCabinet(count);
        count = this.service.getAirCountByRoom("数据机房%");
        dataRoom.setAir(count);
        count = this.service.getCabinetCountByRoom("网络机房%");
        netRoom.setCabinet(count);
        count = this.service.getAirCountByRoom("网络机房%");
        netRoom.setAir(count);
        result.put("dataRoom", dataRoom);
        result.put("netRoom", netRoom);

        return Result.ok(result);
    }

    @Override
    protected  void beforeImportExcel(List<MCabinet> list){
        list.forEach(item->{
            if(org.apache.commons.lang.StringUtils.isNotEmpty(item.getMachineRoom())){
                item.setMachineRoom(item.getMachineRoom().trim());
            }
            if(org.apache.commons.lang.StringUtils.isNotEmpty(item.getPersonLiable())){
                item.setPersonLiable(item.getPersonLiable().trim());
            }
        });
    }

    @Override
    protected void afterImportExcel(List<MCabinet> list){
        UpdateWrapper<MCabinet> updateWrapper = new UpdateWrapper<>();

        updateWrapper.clear();
        updateWrapper.lambda().isNull(MCabinet::getMachineRoomId);
        updateWrapper.setSql("Machine_Room_Id=(select id from m_machine_room where machine_room=name LIMIT 1)");
        this.service.update(updateWrapper);

        updateWrapper.clear();
        updateWrapper.lambda().isNull(MCabinet::getPersonLiableId);
        updateWrapper.setSql("person_liable_id=(select id from sys_user where person_liable=realname LIMIT 1)");
        this.service.update(updateWrapper);
    }
}
